import asyncio
import aiohttp
import time
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from common.KubeClient import KubeClient

async def get_params(session, url):
    try:
        async with session.get(url) as resp:
            json_dict = await resp.json()
            return json_dict
    except aiohttp.ClientError as client_error:
        print(client_error)
        return False

async def http_call_async(nodes):
    async with aiohttp.ClientSession() as session:
        tasks = []
        for node in nodes:
            url = 'http://' + node + ':5001'
            tasks.append(asyncio.ensure_future(get_params(session, url)))
        gather_list = await asyncio.gather(*tasks)
        return gather_list

def filtered_list(q_list,quota):
    job_list = []
    df = pd.DataFrame(q_list)
    cols_to_norm = [quota['type'], 'data']
    columns = df[cols_to_norm]
    new_df = columns.copy()
    df[cols_to_norm] = MinMaxScaler().fit_transform(df[cols_to_norm])
    df['score'] = df['data'] * quota['weight'] + df['cpu'] * (1 - quota['weight'])
    df = pd.merge(df, new_df, left_index=True, right_index=True)
    df = df.sort_values(by=['score'], ascending=False)
    if quota['algorithm'] == 1:
        total = 0
        for n in df.to_dict('records'):
            if total >= quota['require_data']:
                break
            else:
                job_list.append(n)
                total = total + n['data_y']
        return job_list
    elif quota['algorithm'] == 2:
        train_df = df.iloc[0:(int(len(df)*(quota['node_percent'])))].copy()
        train_df['role'] = 0
        job_list = train_df.to_dict('records')
    return job_list

def data_study_list(nodes,quota):
    qualified_node_list = []
    gather_list = asyncio.run(http_call_async(nodes))
    for g in gather_list:
        if g != False:
            if g[quota['type']] > quota['pu'] \
                and g['ram'] > quota['ram'] \
                and g['disk'] > quota['disk']\
                and g['data'] > 0:
                qualified_node_list.append(g)
    if len(qualified_node_list) == 0:
        return []
    else:
        return filtered_list(qualified_node_list,quota)

# if __name__=='__main__':
#
#     job = {
#         'name':'job01',
#         'image': 'pi',
#         'command': 'perl',
#         'type': 'cpu',
#         'weight': 0.8,  # weight for
#         'train_rate': 0.4, # 0-1
#     }
#     resource = {
#         'pu': 150,
#         'disk': 150,
#         'ram': 150,
#     }
#     kj = KubeClient()
#     nodes = kj.list_node()
#     input_nodes = []
#     for n in nodes:
#         if n['status'] == "True":
#             input_nodes.append(n['ipaddr'])
#     print(data_study_list(input_nodes,job,resource))